package com.nitobi.coop.service
{
	import com.hurlant.util.Base64;
	import com.nitobi.coop.model.CoopModel;
	import com.nitobi.coop.vo.EntryVO;
	import com.nitobi.coop.vo.GroupVO;
	import com.nitobi.coop.vo.UserVO;
	import com.nitobi.util.Constants;
	import com.nitobi.util.Encryption;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLRequestMethod;
	
	import mx.collections.ArrayCollection;
	import mx.formatters.DateFormatter;
	import mx.utils.StringUtil;
				
	public class CoopService
	{
		private static var instance:CoopService;
		
		private var _url:String;
		private var _user:String;
		private var _pass:String;
		private var _groupId:Number;
		private var _headers:Array = [];
		
		public var model:CoopModel;
		
		public function CoopService():void
		{
			if( CoopService.instance != null ) 
			{
				throw new Error( "CoopService is a singleton." );
			}			
		}

		public static function getInstance():CoopService
		{
			if( CoopService.instance == null ) 
			{
				CoopService.instance = new CoopService();
			}
			return CoopService.instance;
		}	
				
		public function init():void
		{
			model = CoopModel.getInstance();
			
			_url = Constants.COOP_URL;
			_user = Encryption.readEncryptedStringSetting("coopUser");
			_pass = Encryption.readEncryptedStringSetting("coopPass");

			var userData:String = Base64.encode(_user + ":" + _pass);
			var authorize:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + userData);
			var accept:URLRequestHeader = new URLRequestHeader("Accept", "application/xml");
			_headers.push(authorize);
			_headers.push(accept);			
			
			getCoopGroupsForUser(populateGroupList, coopError);	
		}
		
		public function populateGroupList(e:Event):void
		{
			trace("populateGroupList");
			var groupAC:ArrayCollection = new ArrayCollection();
			var xml:XML = new XML(e.target.data);
			var groupList:XMLList = new XMLList(xml.children());	
			
			for each (var group:XML in groupList)
			{
				var groupVO:GroupVO = new GroupVO();
				groupVO._createdAt = group["created-at"];
				groupVO._id = group.id;
				if (isNaN(_groupId))
				{
					_groupId = group.id;
				}
				groupVO._name = group.name;
				groupVO._timeZone = group.timezone;
				groupVO._updatedAt = group["updated-at"];
				groupAC.addItem(groupVO);
			}
			model.groupListAC = groupAC;
			// sets the first group loaded into the groupAC as the groupId
			model.groupId = groupAC[groupAC.length-1]._id;
			
			getCoopGroupData(_groupId, populateGroupEntries, coopError);
		}
		
		public function getCoopGroupsForUser(callback:Function, fail:Function):void
		{
			trace("getCoopGroupsForUser");

			var request:URLRequest = new URLRequest(_url + "/groups/");
			request.contentType = "application/xml";
			request.requestHeaders = _headers;
			request.data = "";
			request.method = URLRequestMethod.GET;
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			loader.addEventListener(Event.COMPLETE, callback);
			loader.addEventListener(IOErrorEvent.IO_ERROR, fail);
			loader.load(request);			
			
		}
		
		public function populateGroupEntries(e:Event):void
		{
			trace("populateGroupEntries");
			var groupEntriesAC:ArrayCollection = new ArrayCollection();
			var xml:XML = new XML(e.target.data);
			var groupEntriesList:XMLList = new XMLList(xml.children());
			var dailyHours:Number = 0;
			
			for each (var entry:XML in groupEntriesList)
			{
				var entryVO:EntryVO = new EntryVO();
				entryVO._type = entry.type;
				entryVO._updatedAt = entry["updated-at"];
				entryVO._text = StringUtil.trim(entry.text);
				entryVO._groupId = entry["group-id"];
				entryVO._id = entry.id;
				entryVO._createdAt = entry["created-at"];
				entryVO._spentAt = entry["spent-at"];
				entryVO._timerStartedAt = entry["timer-started-at"];
				entryVO._hours = entry.hours;
				if (entryVO._timerStartedAt.length > 0)
				{
					entryVO._timerStartedAt = Constants.TIMER_RUNNING;
				}
				else
				{
					if (entryVO._spentAt.length > 0)
						entryVO._timerStartedAt = Constants.TIMER_STOPPED;
					else
						entryVO._timerStartedAt = "";
				}
				var userXML:XML = new XML(entry.user);
				
				var user:UserVO = new UserVO();
				user._email = userXML.email;
				user._name = userXML.name;
				user._avatarUrl = userXML["avatar-thumb-url"];
				user._id = userXML.id;
				
				entryVO._user = user;
				entryVO._userName = user._name;
				groupEntriesAC.addItem(entryVO);
				dailyHours += entryVO._hours;
			}		
			model.groupDailyEntriesAC = groupEntriesAC;
			model.todaysHours = dailyHours;
		}		
		
		public function getCoopGroupData(groupId:Number, callback:Function, fail:Function):void
		{
			trace("getCoopGroupData");
			
			var dateFormatter:DateFormatter = new DateFormatter();
			dateFormatter.formatString = "YYYYMMDD";	
			var date:String = dateFormatter.format(new Date);			
			
			var request:URLRequest = new URLRequest(_url + "/groups/" + groupId + "/" + date);
			request.contentType = "application/xml";
			request.requestHeaders = _headers;
			request.data = "";
			request.method = URLRequestMethod.GET;
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			loader.addEventListener(Event.COMPLETE, callback);
			loader.addEventListener(IOErrorEvent.IO_ERROR, fail);
			loader.load(request);			
		}

		public function populateUserInfo(e:Event):void
		{
			var xml:XML = new XML(e.target.data);	
			trace(xml);		
		}

		public function getCoopUserInfo(callback:Function, fail:Function):void
		{
			trace("getCoopUserInfo");

			var request:URLRequest = new URLRequest(_url + "/users/");
			request.contentType = "application/xml";
			request.requestHeaders = _headers;
			request.data = "";
			request.method = URLRequestMethod.GET;
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			loader.addEventListener(Event.COMPLETE, callback);
			loader.addEventListener(IOErrorEvent.IO_ERROR, fail);
			loader.load(request);				
		}
		
		public function createCoopEntry(groupId:Number, note:String, callback:Function, fail:Function):void
		{
			trace("createCoopEntry");

			var requestParams:XML = <status>{note}</status>				

			var request:URLRequest = new URLRequest(_url + "/groups/" + groupId + "/statuses");
			request.contentType = "application/xml";
			request.requestHeaders = _headers;
			request.data = requestParams;
			request.method = URLRequestMethod.POST;
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			loader.addEventListener(Event.COMPLETE, callback);
			loader.addEventListener(IOErrorEvent.IO_ERROR, fail);
			loader.load(request);				
		}
				
		public function coopError(e:IOErrorEvent):void
		{
			trace("coopError");
		}
		
	}
}